home *** CD-ROM | disk | FTP | other *** search
/ Aminet 13 / Aminet 13 - August 1996.iso / MainActor / LoadMPEG / mpeg / tools / src / ppm2cyuv.c < prev   
C/C++ Source or Header  |  1993-09-01  |  8KB  |  284 lines

  1. /*************************************************************
  2. Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
  3. PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
  4. Group. If you use this software, you agree to the following: This
  5. program package is purely experimental, and is licensed "as is".
  6. Permission is granted to use, modify, and distribute this program
  7. without charge for any purpose, provided this license/ disclaimer
  8. notice appears in the copies.  No warranty or maintenance is given,
  9. either expressed or implied.  In no event shall the author(s) be
  10. liable to you or a third party for any special, incidental,
  11. consequential, or other damages, arising out of the use or inability
  12. to use the program for any purpose (or the loss of data), even if we
  13. have been advised of such possibilities.  Any public reference or
  14. advertisement of this source code should refer to it as the Portable
  15. Video Research Group (PVRG) code, and not by any author(s) (or
  16. Stanford University) name.
  17. *************************************************************/
  18. /*
  19. ************************************************************
  20. ppm2cyuv.c
  21.  
  22. This program separates a raw ppm input file into component YUV files
  23. with a sampling ratio of 4:1:1 (the same pattern as MPEG 4:2:0).  The
  24. output is placed in .Y .U .V by default.
  25.  
  26. The ppm description and files are part of Jef Poskanzer's PBMPLUS
  27. library.  This is just a short-cut program to do a simple YUV
  28. conversion.
  29.  
  30. -----
  31. Modifications by Son H. Le on 01-Sep-93
  32.   o replaced all exit(-1) with exit(0)
  33.   o added exit(0) after convertRGB2YUV()
  34.   o added #include <stdlib.h> and <string.h>
  35.   o added prototype convertRGB2YUV()
  36. ************************************************************
  37. */
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42.  
  43. #define PPM_MAGIC1 'P'
  44. #define PPM_MAGIC2 '3'
  45. #define RPPM_MAGIC2 '6'
  46. #define FIXNUM 16
  47.  
  48. #define FIX(a,b) ((int)((a)*(1<<(b))))
  49. #define UNFIX(a,b) ((a+(1<<(b-1)))>>(b))
  50.  
  51. /* Approximate 255 by 256 */
  52. #define CCIRUV(x) (((((x)-128)*224)>>8)+128)
  53. #define CCIRY(x) (((((x))*219)>>8)+16)
  54.  
  55. #define CLIP(t) (((t)>255)?255:(((t)<0)?0:(t)))
  56. #define GETY(r,g,b) UNFIX((FIX(0.299,FIXNUM)*(r)+\
  57.                FIX(0.587,FIXNUM)*(g)+\
  58.                FIX(0.144,FIXNUM)*(b)),FIXNUM)
  59. #define GETU(r,g,b) UNFIX((FIX(-0.1687,FIXNUM)*(r)+\
  60.                FIX(-0.3313,FIXNUM)*(g)+\
  61.                FIX(0.5,FIXNUM)*(b)),FIXNUM)
  62. #define GETV(r,g,b) UNFIX((FIX(0.5,FIXNUM)*(r)+\
  63.                FIX(-0.4187,FIXNUM)*(g)+\
  64.                FIX(-0.0813,FIXNUM)*(b)),FIXNUM)
  65.  
  66. char *suffix[3] = {".Y",".U",".V"};
  67.  
  68. void convertRGB2YUV(FILE *inp,FILE *outy, FILE *outu,FILE *outv, int CCIR601);
  69.  
  70. void
  71. convertRGB2YUV(inp, outy, outu, outv, CCIR601)
  72.      FILE *inp,*outy,*outu,*outv;
  73.      int CCIR601;
  74. {
  75.   int i,j;
  76.   int r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4;
  77.   int magic1, magic2;
  78.   int incols,inrows,maxval;
  79.   int outcols,outrows;
  80.   int temp;
  81.   char inpstring[256];
  82.   unsigned char *temprgb1, *temprgb2, *tempy1, *tempy2, *tempu, *tempv;
  83.   unsigned char *rgb1p, *rgb2p, *y1p, *y2p, *up, *vp;
  84.  
  85.   magic1=fgetc(inp);
  86.   magic2=fgetc(inp);
  87.   fgetc(inp);            /* dispense with \n */
  88.   fgets(inpstring,256,inp);
  89.   sscanf(inpstring,"%d %d",&incols, &inrows);
  90.   fgets(inpstring,256,inp);
  91.   sscanf(inpstring,"%d",&maxval);
  92.  
  93.   /* printf("%d %d %d %d %d\n",magic1,magic2,incols,inrows,maxval); */
  94.   if (maxval>255)
  95.     {
  96.       printf("Only handles maximum value of 255 < (found)%d\n",maxval);
  97.       exit(0);
  98.     }
  99.   if (magic1 != PPM_MAGIC1)
  100.     {
  101.       printf("Bad magic number 1; not ppm file?\n");
  102.       exit(0);
  103.     }
  104.   if (magic2 != RPPM_MAGIC2)
  105.     {
  106.       printf("Bad magic number 2; not raw ppm file?\n");
  107.       exit(0);
  108.     }
  109.  
  110.   if (inrows&1) outrows = inrows-1;
  111.   else outrows = inrows;
  112.   if (incols&1) outcols = incols-1;
  113.   else outcols = incols;
  114.  
  115.   printf("input size: %dx%d\t output size: %dx%d\n",
  116.      incols,inrows,outcols,outrows);
  117.  
  118.   temprgb1 = (unsigned char *) calloc(incols*3,sizeof(char));
  119.   temprgb2 = (unsigned char *) calloc(incols*3,sizeof(char));
  120.   tempy1 = (unsigned char *) calloc(outcols,sizeof(char));
  121.   tempy2 = (unsigned char *) calloc(outcols,sizeof(char));
  122.   tempu = (unsigned char *) calloc(outcols>>1,sizeof(char));
  123.   tempv = (unsigned char *) calloc(outcols>>1,sizeof(char));
  124.  
  125.   for(i=0;i<(outrows>>1);i++)
  126.     {
  127.       fread(temprgb1,1,incols*3*sizeof(char),inp);
  128.       fread(temprgb2,1,incols*3*sizeof(char),inp);
  129.       rgb1p = temprgb1;
  130.       rgb2p = temprgb2;
  131.  
  132.       y1p = tempy1;
  133.       y2p = tempy2;
  134.       up = tempu;
  135.       vp = tempv;
  136.  
  137.       for(j=0;j<(outcols>>1);j++)
  138.     {
  139.       r1 = *(rgb1p++);
  140.       g1 = *(rgb1p++);
  141.       b1 = *(rgb1p++);
  142.       r2 = *(rgb1p++);
  143.       g2 = *(rgb1p++);
  144.       b2 = *(rgb1p++);
  145.  
  146.       r3 = *(rgb2p++);
  147.       g3 = *(rgb2p++);
  148.       b3 = *(rgb2p++);
  149.       r4 = *(rgb2p++);
  150.       g4 = *(rgb2p++);
  151.       b4 = *(rgb2p++);
  152.  
  153.       if (CCIR601)
  154.         {
  155.           temp=GETY(r1,g1,b1);
  156.           temp=CLIP(temp);
  157.           *(y1p++) = CCIRY(temp);
  158.           temp=GETY(r2,g2,b2);
  159.           temp=CLIP(temp);
  160.           *(y1p++) = CCIRY(temp);
  161.           temp=GETY(r3,g3,b3);
  162.           temp=CLIP(temp);
  163.           *(y2p++) = CCIRY(temp);
  164.           temp=GETY(r4,g4,b4);
  165.           temp=CLIP(temp);
  166.           *(y2p++) = CCIRY(temp);
  167.  
  168.           /* We use a box filter for decimation */
  169.  
  170.           temp = ((GETU(r1+r2+r3+r4,g1+g2+g3+g4,b1+b2+b3+b4)
  171.                +(1<<9)+(1<<1))>>2);
  172.           temp=CLIP(temp);
  173.           *(up++) = CCIRUV(temp);
  174.           temp = ((GETV(r1+r2+r3+r4,g1+g2+g3+g4,b1+b2+b3+b4)
  175.                +(1<<9)+(1<<1))>>2);
  176.           temp=CLIP(temp);
  177.           *(vp++) = CCIRUV(temp);
  178.         }
  179.       else
  180.         {
  181.           temp=GETY(r1,g1,b1);
  182.           *(y1p++) = CLIP(temp);
  183.           temp=GETY(r2,g2,b2);
  184.           *(y1p++) = CLIP(temp);
  185.           temp=GETY(r3,g3,b3);
  186.           *(y2p++) = CLIP(temp);
  187.           temp=GETY(r4,g4,b4);
  188.           *(y2p++) = CLIP(temp);
  189.  
  190.           /* We use a box filter for decimation */
  191.  
  192.           temp = ((GETU(r1+r2+r3+r4,g1+g2+g3+g4,b1+b2+b3+b4)
  193.                +(1<<9)+(1<<1))>>2);
  194.           *(up++) = CLIP(temp);
  195.           temp = ((GETV(r1+r2+r3+r4,g1+g2+g3+g4,b1+b2+b3+b4)
  196.                +(1<<9)+(1<<1))>>2);
  197.           *(vp++) = CLIP(temp);
  198.         }
  199.     }
  200.       fwrite(tempy1,1,outcols*sizeof(char),outy);
  201.       fwrite(tempy2,1,outcols*sizeof(char),outy);
  202.       fwrite(tempu,1,(outcols>>1)*sizeof(char),outu);
  203.       fwrite(tempv,1,(outcols>>1)*sizeof(char),outv);
  204.     }
  205. }
  206.  
  207. int
  208. main(argc, argv)
  209.      int argc;
  210.      char **argv;
  211.  
  212. {
  213.   int i;
  214.   int CCIR601=0;
  215.   int suffixcount=0;
  216.   char *infile,*outfile;
  217.   char outfiley[256];
  218.   char outfileu[256];
  219.   char outfilev[256];
  220.   FILE *inp,*outy,*outu,*outv;
  221.  
  222.   if (argc<3)
  223.     {
  224.       printf("ppm2cyuv infile outfile [-z suffix]* [-CCIR601]\n");
  225.       printf("\n");
  226.       printf("infile is the input ppm file\n");
  227.       printf("outfile is the output file with outfile.Y outfile.U outfile.V\n");
  228.       printf("-z specifies alternate suffixes:\n");
  229.       printf("          e.g. ppm2cyuv inp.ppm out -z .y -z .cb -z .cr\n");
  230.       printf("          will output out.y, out.cb, out.cr, respectively\n");
  231.       printf("-CCIR601 specifies CCIR601 yuv space (default JFIF).\n");
  232.       exit(0);
  233.     }
  234.  
  235.   for(i=3;i<argc;i++)
  236.     {
  237.       if (!strcmp(argv[i],"-z"))
  238.     {
  239.       if (suffixcount==3)
  240.         {
  241.           printf("too many suffixes\n");
  242.           exit(0);
  243.         }
  244.       suffix[suffixcount++] = argv[++i];
  245.     }
  246.       else if (!strcmp(argv[i],"-CCIR601"))
  247.     CCIR601=1;
  248.       else
  249.     {
  250.       printf("unknown option: %s\n",argv[i]);
  251.       exit(0);
  252.     }
  253.     }
  254.  
  255.   infile = argv[1];
  256.   outfile = argv[2];
  257.   sprintf(outfiley,"%s%s",outfile,suffix[0]);
  258.   sprintf(outfileu,"%s%s",outfile,suffix[1]);
  259.   sprintf(outfilev,"%s%s",outfile,suffix[2]);
  260.  
  261.   if (!(inp=fopen(infile,"r")))
  262.     {
  263.       printf("cannot open file: %s\n",infile);
  264.       exit(0);
  265.     }
  266.   if (!(outy=fopen(outfiley,"w")))
  267.     {
  268.       printf("cannot open file: %s\n",outfiley);
  269.       exit(0);
  270.     }
  271.   if (!(outu=fopen(outfileu,"w")))
  272.     {
  273.       printf("cannot open file: %s\n",outfileu);
  274.       exit(0);
  275.     }
  276.   if (!(outv=fopen(outfilev,"w")))
  277.     {
  278.       printf("cannot open file: %s\n",outfilev);
  279.       exit(0);
  280.     }
  281.   convertRGB2YUV(inp,outy,outu,outv,CCIR601);
  282.   exit(0);
  283. }
  284.